/*---------------------------------------------------
-----------------------------------------------------
Filename:	notifier.m
Version:	1.2

Type:		maki/notifier
Date:		14. Mrz. 2007 - 14:50 
Author:		Martin Poehlmann aka Deimos
E-Mail:		martin@skinconsortium.com
Internet:	www.skinconsortium.com
		www.martin.deimos.de.vu

Note:		Based on notifier.m from Winamp Modern
-----------------------------------------------------
---------------------------------------------------*/

#include <lib/std.mi>
#include attribs/init_notifier.m

Function reset();
Function createNotifier();
Function showNotifier(Int w);
Function onNext();

Function Int fillNextTrackInfo(String corneroverride);
Function Int fillCustomInfo(String customstring);

Function checkPref(int bypassfs);

Global Container notifier_container;
Global Layout notifier_layout;
Global Timer notifier_timer;
Global String last_autotitle;

Global Boolean b_tohide = 0;

// ------------------------------------------------------------------------------
// init
// ------------------------------------------------------------------------------
System.onScriptLoaded() {
	initAttribs_notifier();
	notifier_timer = new Timer;
}

// ------------------------------------------------------------------------------
// shutdown
// ------------------------------------------------------------------------------
System.onScriptUnloading() {
	delete notifier_timer;
}

// ------------------------------------------------------------------------------
// called by the system when the global hotkey for notification is pressed
// ------------------------------------------------------------------------------
System.onShowNotification() {
	if (checkPref(1)) return;
	createNotifier();
	String str;
	if (getStatus() == STATUS_PLAYING) str = "Playing";
	if (getStatus() == STATUS_PAUSED) str = "Playback Paused";
	if (getStatus() == STATUS_STOPPED) str = "Playback Stopped";
	showNotifier(fillNextTrackInfo(str));
	complete; // prevents other scripts from getting the message
	return 1; // tells anybody else that might watch the returned value that, yes, we implemented that
}

// ------------------------------------------------------------------------------
// called by the system when the title for the playing item changes, this could be the result of the player
// going to the next track, or of an update in the track title
// ------------------------------------------------------------------------------
System.onTitleChange(String newtitle) {
	if (last_autotitle == newtitle) return;
	if (StrLeft(newtitle, 1) == "[") {
		if (StrLeft(newtitle, 7) == "[Buffer" ||
				StrLeft(newtitle, 4) == "[ICY") return;
	}
	last_autotitle = newtitle;
	onNext();
}

// ------------------------------------------------------------------------------
// called by the system when the user clicks the next button
// ------------------------------------------------------------------------------
onNext() {
	if (checkPref(0)) return;
	createNotifier();
	showNotifier(fillNextTrackInfo(""));
}

// ------------------------------------------------------------------------------
// called by the system when the user clicks the play button
// ------------------------------------------------------------------------------
System.onPlay() {
	if (checkPref(0)) return;
	createNotifier();
	showNotifier(fillNextTrackInfo("Playing"));
}

// ------------------------------------------------------------------------------
// called by the system when the user clicks the pause button
// ------------------------------------------------------------------------------
System.onPause() {
	if (checkPref(0)) return;
	createNotifier();
	showNotifier(fillCustomInfo("Playback Paused"));
}

// ------------------------------------------------------------------------------
// called by the system when the user clicks the pause button again
// ------------------------------------------------------------------------------
System.onResume() {
	if (checkPref(0)) return;
	createNotifier();
	showNotifier(fillNextTrackInfo("Resuming Playback"));
}

// ------------------------------------------------------------------------------
// called by the system when the user clicks the play button
// ------------------------------------------------------------------------------
System.onStop() {
	if (checkPref(0)) return;
	createNotifier();
	showNotifier(fillCustomInfo("End of Playback"));
}

// ------------------------------------------------------------------------------
// checks if we should display anything
// ------------------------------------------------------------------------------
Int checkPref(int bypassfs) {
	if (!bypassfs && notifier_hideinfullscreen_attrib.getData() == "1" && isVideoFullscreen()) return 1;
	if (notifier_never_attrib.getData() == "1") return 1;
	if (notifier_minimized_attrib.getData() == "1" && !isMinimized()) return 1;
	if (notifier_windowshade_attrib.getData() == "1") {
		if (isMinimized()) return 0;
		Container c = getContainer("main");
		if (!c) return 1;
		Layout l = c.getCurLayout();
		if (!l) return 1;
		if (l.getId() != "shade") return 1;
	}
	return 0;
}

// ------------------------------------------------------------------------------
// fade in/out completed
// ------------------------------------------------------------------------------
notifier_layout.onTargetReached() {
	if (b_tohide) {
		notifier_layout.setAlpha(0);
		reset();	
		return;
	}
	int a = notifier_layout.getAlpha();
	if (a == 255 && !b_tohide) {
		notifier_timer.setDelay(StringToInteger(notifier_holdtime_attrib.getData()));
		notifier_timer.start();
	}
	else if (a == 0) {
		reset();
	}
}

// ------------------------------------------------------------------------------
// hold time elapsed
// ------------------------------------------------------------------------------
notifier_timer.onTimer() {
	stop();
	if (notifier_fdout_alpha.getData() == "1") {
		if (notifier_layout.isTransparencySafe()) {
			notifier_layout.setTargetA(0);
			notifier_layout.setTargetSpeed(StringToInteger(notifier_fadeouttime_attrib.getData()) / 1000);
			notifier_layout.gotoTarget();
			return;
		} else {
			reset();
			return;
		}
	} else if (notifier_fdout_vslide.getData() == "1") {
		b_tohide = 1;
		int sy;
		int geth;
		if (notifier_loc_vport_attrib.getData() == "1")
		{
			geth = getViewportHeight();
		}
		else
		{
			geth = getMonitorHeight();
		}
		if (notifier_layout.getGuiY() == 2) sy = -80;
		else sy = geth + 80;
		notifier_layout.setTargetY(sy);
		notifier_layout.setTargetSpeed(StringToInteger(notifier_fadeintime_attrib.getData()) / 1000);
		notifier_layout.gotoTarget();
		return;
	} else	{
		if (b_tohide) return;
		b_tohide = 1;
		int sx;
		int getw;
		if (notifier_loc_vport_attrib.getData() == "1")
		{
			getw = getViewportWidth();
		}
		else
		{
			getw = getMonitorWidth();
		}
		if (notifier_layout.getGuiX() == 2) sx = -notifier_layout.getWidth();
		else sx = getw + notifier_layout.getWidth();
		notifier_layout.setTargetX(sx);
		notifier_layout.setTargetSpeed(StringToInteger(notifier_fadeintime_attrib.getData()) / 1000);
		notifier_layout.gotoTarget();
		return;
	}
}

// ------------------------------------------------------------------------------
// when notifier is clicked, bring back the app from minimized state if its minimized and focus it
// ------------------------------------------------------------------------------
notifier_layout.onLeftButtonDown(int x, int y) {
	notifier_timer.stop();
	notifier_layout.cancelTarget();
	reset();
	restoreApplication();
	activateApplication();
}

// ------------------------------------------------------------------------------
// close the notifier window, destroys the container automatically because it's dynamic
// ------------------------------------------------------------------------------
reset() {
	notifier_container.close();
	notifier_container = NULL;
	notifier_layout = NULL;
}

// ------------------------------------------------------------------------------
createNotifier() {
	if (notifier_container == NULL) {
		notifier_container = newDynamicContainer("notifier");
		if (!notifier_container) return; // reinstall duh!
		if (isDesktopAlphaAvailable())
			notifier_layout = notifier_container.getLayout("desktopalpha");
		else
			notifier_layout = notifier_container.getLayout("normal");
		if (!notifier_layout) return; // reinstall twice, man
	} else {
		notifier_layout.cancelTarget();
		notifier_timer.stop();
	}
}

// ------------------------------------------------------------------------------
showNotifier(int w) {
	DebugString(IntegerToString(w), 0);
	b_tohide = 0;
	int x; int y;
	int sy; int sx;
	w = w + 90;

	int getx, gety, geth, getw;
	if (notifier_loc_vport_attrib.getData() == "1")
	{
		getx = getViewportLeft();
		gety = getViewportTop();
		geth = getViewportHeight();
		getw = getViewportWidth();
	}
	else
	{
		getx = 0;
		gety = 0;
		geth = getMonitorHeight();
		getw = getMonitorWidth();		
	}
	if (notifier_loc_br_attrib.getData() == "1") {
		x = getw + getx - w - 2;
		y = geth + gety - 80 - 2;
	}
	else if (notifier_loc_bl_attrib.getData() == "1") {
		x = 2;
		y = geth + gety - 80 - 2;
	}
	else if (notifier_loc_bc_attrib.getData() == "1") {
		x = (getw + getx - w) / 2;
		y = geth + gety - 80 - 2;
	}
	else if (notifier_loc_tr_attrib.getData() == "1") {
		x = getw + getx - w - 2;
		y = 2;
	}
	else if (notifier_loc_tc_attrib.getData() == "1") {
		x = (getw + getx - w) / 2;
		y = 2;
	}
	else	{
		x = 2;
		y = 2;
	}
	if (notifier_fdin_alpha.getData() == "1") {
		if (!notifier_layout.isVisible()) notifier_layout.resize(x, y, w, 80);
		else
		{
			notifier_layout.resize(notifier_layout.getguiX(), y, notifier_layout.getGuiW(), 80);
		}
		if (notifier_layout.isTransparencySafe()) {
			notifier_layout.show();
			notifier_layout.settargetA(255);
			notifier_layout.setTargetX(x);
			notifier_layout.setTargetY(y);
			notifier_layout.setTargetW(w);
			notifier_layout.setTargetH(80);
			notifier_layout.setTargetSpeed(StringToInteger(notifier_fadeintime_attrib.getData()) / 1000);
			notifier_layout.gotoTarget();
		} else {
			notifier_layout.setAlpha(255);
			notifier_layout.show();
			notifier_layout.settargetA(255);
			notifier_layout.setTargetX(x);
			notifier_layout.setTargetY(y);
			notifier_layout.setTargetW(w);
			notifier_layout.setTargetH(80);
			notifier_timer.setDelay(StringToInteger(notifier_holdtime_attrib.getData()));
			notifier_timer.start();
		}
	} else if (notifier_fdin_vslide.getData() == "1") {
		if (y == 2) sy = -80;
		else sy = geth + 80;
		if (!notifier_layout.isVisible()) notifier_layout.resize(x, sy, w, 80);
		else
		{
			notifier_layout.resize(notifier_layout.getguiX(), y, notifier_layout.getGuiW(), 80);
		}
		notifier_layout.show();
		notifier_layout.setAlpha(255);
		notifier_layout.setTargetX(x);
		notifier_layout.setTargetY(y);
		notifier_layout.setTargetW(w);
		notifier_layout.setTargetH(80);
		notifier_layout.setTargetSpeed(StringToInteger(notifier_fadeintime_attrib.getData()) / 1000);
		notifier_layout.gotoTarget();
	} else	{
		if (x < (getw + getx)/2) sx = -w;
		else sx = getw + w;
		if (!notifier_layout.isVisible()) notifier_layout.resize(sx, y, w, 80);
			else
		{
			notifier_layout.resize(notifier_layout.getguiX(), y, notifier_layout.getGuiW(), 80);
		}
		notifier_layout.show();
		notifier_layout.setAlpha(255);
		notifier_layout.setTargetX(x);
		notifier_layout.setTargetY(y);
		notifier_layout.setTargetW(w);
		notifier_layout.setTargetH(80);
		notifier_layout.setTargetSpeed(StringToInteger(notifier_fadeintime_attrib.getData()) / 1000);
		notifier_layout.gotoTarget();
	}
}

// ------------------------------------------------------------------------------
Int fillNextTrackInfo(String corneroverride) {
	Int maxv = 0;
	Int stream = 0;
	Group p = notifier_layout;
	Text plentry = p.findObject("plentry");
	Text nexttrack = p.findObject("nexttrack");
	Text _title = p.findObject("title");
	Text album = p.findObject("album");
	Text artist = p.findObject("artist");
	Text endofplayback = p.findObject("endofplayback");
	Text s_plentry = p.findObject("plentry.shadow");
	Text s_nexttrack = p.findObject("nexttrack.shadow");
	Text s_title = p.findObject("title.shadow");
	Text s_album = p.findObject("album.shadow");
	Text s_artist = p.findObject("artist.shadow");
	Text s_endofplayback = p.findObject("endofplayback.shadow");

	DebugString("got callback for " + getPlayItemString(), 0);
	if (StrLeft(getPlayItemString(), 7) == "http://") stream = 1;

	if (endofplayback) endofplayback.hide();

	if (plentry)
	{ 
		plentry.setText(integerToString(getPlaylistIndex()+1)+" of "+integerToString(getPlaylistLength()));
		plentry.show();
		s_plentry.setText(integerToString(getPlaylistIndex()+1)+" of "+integerToString(getPlaylistLength()));
		s_plentry.show();
	}
	if (nexttrack) {
		if (corneroverride == "") {
			if (!stream) {
				if (!isVideo())
				{
					nexttrack.setText("New track");
					s_nexttrack.setText("New track");
				}
				else
				{
					nexttrack.setText("New video");
					s_nexttrack.setText("New video");					
				}
			}
			else
			{
				nexttrack.setText("On air");
				s_nexttrack.setText("On air");
			}
		} 
		else
		{
			nexttrack.setText(corneroverride);
			s_nexttrack.setText(corneroverride);
		}
		nexttrack.show();
		s_nexttrack.show();
	}
	if (_title) {
		String str;
		if (!stream)
		{
			_title.setXmlParam("ticker", "0");
			_title.setXmlParam("display", "");
			s_title.setXmlParam("ticker", "0");
			s_title.setXmlParam("display", "");
			str = getPlayitemMetaDataString("title"); 
			if (str == "") str = getPlayitemDisplayTitle();
			String l = getPlayItemMetaDataString("length");
			if (l != "") {
				str += " (" + integerToTime(stringtointeger(l)) + ")";
			}
			_title.setText(str);
			s_title.setText(str);
		}
		else
		{
			_title.setXmlParam("ticker", "1");
			_title.setXmlParam("display", "songtitle");
			_title.setText("");
			s_title.setXmlParam("ticker", "1");
			s_title.setXmlParam("display", "songtitle");
			s_title.setText("");
		}
		_title.show(); 
		s_title.show(); 
	}
	if (artist) { 
		if (!stream) {
			if (isVideo())
			{
				artist.setText(""); 
				s_artist.setText("");
			}
			else
			{
				artist.setText(getPlayitemMetaDataString("artist")); 
				s_artist.setText(getPlayitemMetaDataString("artist"));				
			}
 
		}
		else
		{
			if (isVideo())
			{
				artist.setText("Internet TV"); 
				s_artist.setText("Internet TV");
			}
			else
			{
				artist.setText("Internet Radio"); 
				s_artist.setText("Internet Radio");				
			}

		}
		artist.show(); 
		s_artist.show();
	}
	if (album) { 
		String str;
		if (!stream && !isVideo()) {
			s_album.setXmlParam("display", "");
			album.setXmlParam("display", "");
			str = getPlayitemMetaDataString("album");
			String l = getPlayitemMetaDataString("track");
			if (l != "" && l != "-1") str += " (Track " + l + ")";
			album.setText(str); 
			s_album.setText(str); 
		}
		else
		{
			album.setText("");
			album.setXmlParam("display", "songinfo");
			s_album.setText("");
			s_album.setXmlParam("display", "songinfo");
		}
		album.show(); 
		s_album.show(); 
	}
	maxv = artist.getAutoWidth();
	if (maxv < album.getAutoWidth()) maxv = album.getAutoWidth();
	if (maxv < _title.getAutoWidth()) maxv = _title.getAutoWidth();
	if (maxv < (plentry.getAutoWidth() + 30 + nexttrack.getAutoWidth())) maxv = (plentry.getAutoWidth() + 30 + nexttrack.getAutoWidth());
	if (maxv < 128) maxv = 128;

	guiobject cover = p.findObject("notifier.cover");
	layer cover_bg = p.findObject("notifier.cover.bg");
	cover.show();
	cover_bg.show();

	int getw;
	if (notifier_loc_vport_attrib.getData() == "1")
	{
		getw = getViewportWidth();
	}
	else
	{
		getw = getMonitorWidth();		
	}

	if (maxv > getw/4) maxv = getw/4;
	
	return maxv;
}

// ------------------------------------------------------------------------------
Int fillCustomInfo(String customtext)
{
	Group p = notifier_layout;
	Text plentry = p.findObject("plentry");
	Text nexttrack = p.findObject("nexttrack");
	Text _title = p.findObject("title");
	Text album = p.findObject("album");
	Text artist = p.findObject("artist");
	Text endofplayback = p.findObject("endofplayback");
	Text s_plentry = p.findObject("plentry.shadow");
	Text s_nexttrack = p.findObject("nexttrack.shadow");
	Text s_title = p.findObject("title.shadow");
	Text s_album = p.findObject("album.shadow");
	Text s_artist = p.findObject("artist.shadow");
	Text s_endofplayback = p.findObject("endofplayback.shadow");

	guiobject cover = p.findObject("notifier.cover");
	layer cover_bg = p.findObject("notifier.cover.bg");

	if (plentry) { plentry.hide(); }
	if (nexttrack) nexttrack.hide();
	if (_title) { _title.hide(); }
	if (artist) { artist.hide(); }
	if (album) { album.hide(); }

	if (plentry) { s_plentry.hide(); }
	if (nexttrack) s_nexttrack.hide();
	if (_title) { s_title.hide(); }
	if (artist) { s_artist.hide(); }
	if (album) { s_album.hide(); }

	if (endofplayback) {
		endofplayback.setText(customtext);
		int aw = endofplayback.getAutoWidth();
		endofplayback.show();
		cover.hide();
		cover_bg.hide();
		if (aw > 128)
			return aw;
	}
	return 128;
}

